package com.elinshaw

class Rational(n: Int, d: Int) extends Ordered[Rational] {
  require(d != 0)
  //会被编译到主构造函数中
  println("会被编译到主构造函数中")

  private val g = gcd(n.abs, d.abs)

  val numer: Int = n / g
  val denom: Int = d / g

  def this(n: Int) = this(n, 1) //辅助构造方法

  override def toString = s"$numer/$denom"

  def +(that: Rational) = {
    new Rational(
      numer * that.denom + that.numer * denom,
      denom * that.denom
    )
  }

  def +(i: Int) = {
    new Rational(
      numer + i * denom, denom
    )
  }

  def -(that: Rational) = {
    new Rational(
      numer * that.denom - that.numer * denom,
      denom * that.denom
    )
  }

  def -(i: Int) = {
    new Rational(
      numer - i * denom, denom
    )
  }

  def *(that: Rational) = {
    new Rational(
      numer * that.numer,
      denom * that.denom
    )
  }

  def *(i: Int) = {
    new Rational(
      numer * i, denom
    )
  }

  def /(that: Rational) = {
    new Rational(
      numer * that.denom, that.numer * denom,
    )
  }

  def /(i: Int) = {
    new Rational(
      numer, denom * i
    )
  }

  def lessThan(that: Rational) = this.numer * that.denom < that.numer * that.denom

  def max(that: Rational) = if (this lessThan (that)) that else this

  //最大公约数
  private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)

  /**
   * 混入Ordered特质
   *
   * @param that
   * @return
   */
  override def compare(that: Rational) = (this.numer * that.denom) - (that.numer * this.denom)


}
